﻿using Cloud.Update.Core.Extends;
using Cloud.Update.Core.Models;
using Cloud.Update.Core.Utils;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows;

namespace Cloud.Update.Core
{
    /// <summary>
    /// 包含下载和解压
    /// </summary>
    public class Updates
    {
        //备份
        public delegate void BackUpProgressChangedHandler(BaseModel progress);
        public event BackUpProgressChangedHandler BackUpProgressChanged;
        public delegate void BackUpFinishHandler(bool isSuccess, UpdateState state, string msg = null);
        public event BackUpFinishHandler BackUpFinish;
        //备份还原
        public delegate void UnBackUpProgressChangedHandler(BaseModel progress);
        public event UnBackUpProgressChangedHandler UnBackUpProgressChanged;
        public delegate void UnBackUpFinishHandler(bool isSuccess, UpdateState state, string msg = null);
        public event UnBackUpFinishHandler UnBackUpFinish;

        public delegate void DownloadProgressChangedHandler(DownLoadModel progress);
        public event DownloadProgressChangedHandler DownProgressChanged;
        public delegate void DownloadFinishHandler(bool isSuccess, string downloadPath, UpdateState state, string msg = null,string name = null);
        public event DownloadFinishHandler DownloadFinish;
        public delegate void ZipProgressChangedHandler(ZipModel progress);
        public event ZipProgressChangedHandler UnZipProgressChanged;
        public delegate void UnZipFinishHandler(bool isSuccess, UpdateState state, string msg = null);
        public event UnZipFinishHandler UnZipFinish;

        public delegate void AllFinishHandler();
        public event AllFinishHandler AllFinish;

        public UpdateState DownLoadState;
        public UpdateState UnZipState;

        private ClientParameter clientParameter;

        public string TargetVersion { get; private set; }

        public string AppVersionName { get; set; }

        private int downLoadStep = 0;
        private int unZipStep = 0;
        public Updates(ClientParameter clientParameter)
        {
            this.clientParameter = clientParameter;
        }

        /// <summary>
        /// 程序备份
        /// </summary>
        public Updates Backup() {

            if (!string.IsNullOrEmpty(clientParameter.BackUpPath)) {
                if (!Directory.Exists(clientParameter.BackUpPath))
                {
                    Directory.CreateDirectory(clientParameter.BackUpPath);

                }
                if (Directory.Exists(clientParameter.UnZipPath))
                {
                    //进行数据备份
                    BackUpUtil backUp = new BackUpUtil(clientParameter.UnZipPath, clientParameter.BackUpPath,1);
                    backUp.BackUpProgressChanged += (obj) => {
                        BackUpProgressChanged?.Invoke(obj);
                    };
                    backUp.BackUpFinish += (isSuccess, state, msg) => {
                        BackUpFinish?.Invoke(isSuccess, state, msg);
                    };
                    backUp.Backup();
                }
            }
            DirectoryInfo directInfo = new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory);//获取文件
            if (File.Exists(directInfo.Parent.FullName + @"\version.ini")) {
                System.IO.File.Copy(directInfo.Parent.FullName + @"\version.ini", clientParameter.BackUpPath + @"\version.ini", true);
            }


            return this;
        }
        //备份还原
        public void UnBackUp() {
            if (Directory.Exists(clientParameter.UnZipPath) && Directory.Exists(clientParameter.BackUpPath))
            {
                //进行数据备份
                BackUpUtil backUp = new BackUpUtil(clientParameter.BackUpPath, clientParameter.UnZipPath, clientParameter.IsRestore ? 2 : 1);
                //MessageBox.Show("从" + clientParameter.UnZipPath + "至\n" + clientParameter.BackUpPath);
                backUp.BackUpProgressChanged += (obj) =>
                {
                    //备份还原中...
                    UnBackUpProgressChanged?.Invoke(obj);
                };
                backUp.BackUpFinish += (isSuccess, state, msg) =>
                {
                    DirectoryInfo directInfo = new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory);//获取文件
                    if (File.Exists(clientParameter.BackUpPath + @"\version.ini"))
                    {
                        System.IO.File.Copy(clientParameter.BackUpPath + @"\version.ini", directInfo.Parent.FullName + @"\version.ini", true);
                        File.Delete(clientParameter.UnZipPath + @"\version.ini");
                    }
                    //还原完成
                    UnBackUpFinish?.Invoke(isSuccess, state, msg);
                    
                };
                backUp.Backup();
            }
            else { 
                throw new NotImplementedException("入参为空,请检查[UnZipPath]或[BackUpPath]");
            }
        }

        public void Execute() {
            UnZipState = UpdateState.等待解压;
            DownLoadState = UpdateState.下载中;
            var UpdateVersion = clientParameter.UpdateVersions.FirstOrDefault(x => x.IsUpdate == true);
            TargetVersion = UpdateVersion.Version;
            AppVersionName = UpdateVersion.Name;
            downLoadStep = clientParameter.UpdateVersions.IndexOf(UpdateVersion) + 1;
            UpdateVersion.IsUpdate = false;//标记为false 表示该版本已经更新
            DownloadUtil file = new DownloadUtil(UpdateVersion.Url, this.clientParameter.DownLoadPath, UpdateVersion.Name + ".zip", null);
            file.ProgressChanged += File_ProgressChanged;
            file.DownloadFinish += File_DownloadFinish;
            file.Download();
            
        }

        private void File_DownloadFinish(bool isSuccess, string downloadPath, string fileId, string msg,string name)
        {

            if (isSuccess)
            {
                DownLoadState = UpdateState.下载成功;
                UnZipState = UpdateState.解压中;
                unZipStep = downLoadStep;
                DownloadFinish?.Invoke(isSuccess, downloadPath, DownLoadState, msg,name);
                //解压
                GeneralZipUtil general = new GeneralZipUtil(downloadPath, clientParameter.UnZipPath);
                general.ProgressChanged += General_ProgressChanged;
                general.UnZipFinish += General_UnZipFinish;
                general.UnZip();

            }
            else {
                DownLoadState = UpdateState.下载失败;
                DownloadFinish?.Invoke(isSuccess, downloadPath, DownLoadState, msg,name);
            }
        }

        private void File_ProgressChanged(DownLoadModel progress)
        {
            progress.State = DownLoadState;
            progress.CurrentStep = downLoadStep;
            progress.TotalStep = clientParameter.UpdateVersions.Count;
            DownProgressChanged?.Invoke(progress);
        }


        private void General_UnZipFinish(bool isSuccess, string msg)
        {
            if (isSuccess)
            {
                UnZipState = UpdateState.解压成功;
                UnZipFinish?.Invoke(isSuccess, UnZipState, msg);
                //查看是否还有新版本,有的话继续下载,继续解压,直到全部完成
                var UpdateVersion = clientParameter.UpdateVersions.FirstOrDefault(x => x.IsUpdate == true);
                if (UpdateVersion != null)
                {
                    //UpdateVersion.IsUpdate = false;
                    Execute();
                }
                else {
                    //全部完成 执行后续流程
                    if (!clientParameter.IsUpdateVersion)
                    {   //无需跟新外部版本号
                        AllFinish?.Invoke();
                        System.Threading.Thread.Sleep(1500);
                        StartApp();
                    }
                    else {
                        //外部版本号更新流程
                        DirectoryInfo directInfo = new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory);//获取文件
                        if (VersionExtension.Write("versions", "current_version", TargetVersion, directInfo.Parent.FullName + @"\version.ini"))
                        {
                            VersionExtension.Write("versions", "app_version", AppVersionName, directInfo.Parent.FullName + @"\version.ini");
                            AllFinish?.Invoke();
                            System.Threading.Thread.Sleep(1500);
                            StartApp();
                        }
                        else {
                            UnZipFinish?.Invoke(false, UpdateState.下载失败, "更新未成功\n更新本地版本信息失败,请联系管理员处理!");

                        }
                    }
                    
                    
                }

            }
            else {
                UnZipState = UpdateState.解压失败;
                UnZipFinish?.Invoke(isSuccess, UnZipState, msg);

            }

        }
        private void StartApp()
        {
            try
            {
                if (!string.IsNullOrEmpty(clientParameter.UpdateLogUrl))
                    Process.Start("explorer.exe", clientParameter.UpdateLogUrl);
                if(!string.IsNullOrEmpty(clientParameter.AppName))
                    Process.Start(clientParameter.AppName);
            }
            catch (Exception ex)
            {
               
            }
            finally
            {
                Process.GetCurrentProcess().Kill();
            }
        }
        private void General_ProgressChanged(ZipModel progress)
        {
            progress.State = UnZipState;
            progress.CurrentStep = unZipStep;
            progress.TotalStep = clientParameter.UpdateVersions.Count;
            UnZipProgressChanged?.Invoke(progress);
        }

    }
}
